// index.js
const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'

Page({
  data: {
    localImagePath: '',
    edgeImagePath: '',
    threshold1: 100,
    threshold2: 200,
  },
  bindViewTap() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onChooseAvatar(e) {
    const { avatarUrl } = e.detail
    const { nickName } = this.data.userInfo
    this.setData({
      "userInfo.avatarUrl": avatarUrl,
      hasUserInfo: nickName && avatarUrl && avatarUrl !== defaultAvatarUrl,
    })
  },
  onInputChange(e) {
    const nickName = e.detail.value
    const { avatarUrl } = this.data.userInfo
    this.setData({
      "userInfo.nickName": nickName,
      hasUserInfo: nickName && avatarUrl && avatarUrl !== defaultAvatarUrl,
    })
  },
  getUserProfile(e) {
    // 推荐使用wx.getUserProfile获取用户信息，开发者每次通过该接口获取用户个人信息均需用户确认，开发者妥善保管用户快速填写的头像昵称，避免重复弹窗
    wx.getUserProfile({
      desc: '展示用户信息', // 声明获取用户个人信息后的用途，后续会展示在弹窗中，请谨慎填写
      success: (res) => {
        console.log(res)
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    })
  },
  chooseLocalImage() {
    wx.chooseImage({
      count: 1,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success: (res) => {
        this.setData({
          localImagePath: res.tempFilePaths[0]
        })
      }
    })
  },
  onThreshold1Change(e) {
    this.setData({
      threshold1: e.detail.value
    }, () => {
      // 参数改变后自动执行边缘检测
      if (this.data.localImagePath) {
        this.detectEdges()
      }
    })
  },
  onThreshold2Change(e) {
    this.setData({
      threshold2: e.detail.value
    }, () => {
      // 参数改变后自动执行边缘检测
      if (this.data.localImagePath) {
        this.detectEdges()
      }
    })
  },
  detectEdges() {
    if (!this.data.localImagePath) {
      wx.showToast({
        title: '请先选择图片',
        icon: 'none'
      })
      return
    }

    wx.showLoading({
      title: '处理中...',
    })

    // 创建 canvas context
    const query = wx.createSelectorQuery()
    query.select('#sourceCanvas')
      .fields({ node: true, size: true })
      .exec((res) => {
        const canvas = res[0].node
        const ctx = canvas.getContext('2d')
        
        // 加载图片
        const img = canvas.createImage()
        img.src = this.data.localImagePath
        img.onload = () => {
          // 设置canvas尺寸为图片尺寸
          canvas.width = img.width
          canvas.height = img.height
          
          // 绘制原图到canvas
          ctx.drawImage(img, 0, 0, img.width, img.height)
          
          // 获取图像数据
          const imageData = ctx.getImageData(0, 0, img.width, img.height)
          
          // 执行Canny边缘检测
          this.cannyEdgeDetection(imageData, this.data.threshold1, this.data.threshold2)
            .then(edgeData => {
              // 在结果canvas上显示
              const resultQuery = wx.createSelectorQuery()
              resultQuery.select('#resultCanvas')
                .fields({ node: true, size: true })
                .exec((res) => {
                  const resultCanvas = res[0].node
                  const resultCtx = resultCanvas.getContext('2d')
                  
                  resultCanvas.width = img.width
                  resultCanvas.height = img.height
                  
                  // 将处理后的数据放回canvas
                  resultCtx.putImageData(edgeData, 0, 0)
                  
                  // 将结果canvas转换为图片
                  wx.canvasToTempFilePath({
                    canvas: resultCanvas,
                    success: (res) => {
                      this.setData({
                        edgeImagePath: res.tempFilePath
                      })
                    },
                    fail: (error) => {
                      console.error(error)
                      wx.showToast({
                        title: '处理失败',
                        icon: 'none'
                      })
                    },
                    complete: () => {
                      wx.hideLoading()
                    }
                  })
                })
            })
        }
      })
  },

  // Canny边缘检测算法实现
  cannyEdgeDetection(imageData, lowThreshold, highThreshold) {
    const pixels = imageData.data
    const width = imageData.width
    const height = imageData.height
    const grayscale = new Uint8ClampedArray(width * height)
    
    // 转换为灰度图
    for (let i = 0; i < pixels.length; i += 4) {
      const r = pixels[i]
      const g = pixels[i + 1]
      const b = pixels[i + 2]
      grayscale[i / 4] = (r * 0.299 + g * 0.587 + b * 0.114)
    }
    
    // 简化版的边缘检测
    const result = new Uint8ClampedArray(pixels.length)
    for (let y = 1; y < height - 1; y++) {
      for (let x = 1; x < width - 1; x++) {
        const idx = y * width + x
        
        // 计算梯度
        const gx = 
          -grayscale[idx - width - 1] + grayscale[idx - width + 1] +
          -2 * grayscale[idx - 1] + 2 * grayscale[idx + 1] +
          -grayscale[idx + width - 1] + grayscale[idx + width + 1]
        
        const gy = 
          -grayscale[idx - width - 1] - 2 * grayscale[idx - width] - grayscale[idx - width + 1] +
          grayscale[idx + width - 1] + 2 * grayscale[idx + width] + grayscale[idx + width + 1]
        
        const magnitude = Math.sqrt(gx * gx + gy * gy)
        
        // 应用阈值
        const isEdge = magnitude > lowThreshold && 
                      (magnitude > highThreshold || 
                       this.hasStrongNeighbor(grayscale, x, y, width, height, highThreshold))
        
        const resultIdx = (y * width + x) * 4
        result[resultIdx] = isEdge ? 255 : 0
        result[resultIdx + 1] = isEdge ? 255 : 0
        result[resultIdx + 2] = isEdge ? 255 : 0
        result[resultIdx + 3] = 255
      }
    }
    
    // 修改这里：使用 canvas 创建 ImageData
    const query = wx.createSelectorQuery()
    return new Promise((resolve) => {
      query.select('#resultCanvas')
        .fields({ node: true, size: true })
        .exec((res) => {
          const canvas = res[0].node
          const ctx = canvas.getContext('2d')
          const newImageData = ctx.createImageData(width, height)
          newImageData.data.set(result)
          resolve(newImageData)
        })
    })
  },

  hasStrongNeighbor(grayscale, x, y, width, height, threshold) {
    for (let i = -1; i <= 1; i++) {
      for (let j = -1; j <= 1; j++) {
        if (i === 0 && j === 0) continue
        const nx = x + i
        const ny = y + j
        if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
          if (grayscale[ny * width + nx] > threshold) return true
        }
      }
    }
    return false
  },
})
